import 'package:backend.core/core/domain/entities/web/yookassa/yookassa_transaction.dart';
import 'package:backend.core/core/domain/entities/web/yookassa/yookassa_transaction_revocation_info.dart';
import 'package:backend.purchases/domain/entities/yookassa_api/payments/yookassa_api_succeeded_payment.dart';
import 'package:backend.purchases/domain/helpers/create_web_money_amount_from_yookassa_api_one.dart';
import 'package:backend.purchases/domain/helpers/yookassa/is_yookassa_api_succeeded_payment_revoked.dart';

abstract class UpdateYookassaTransactionFromApiOne {
  YookassaTransaction call({
    required YookassaTransaction transaction,
    required YookassaApiSucceededPayment apiPayment,
  });
}

class UpdateYookassaTransactionFromApiOneImpl implements UpdateYookassaTransactionFromApiOne {
  const UpdateYookassaTransactionFromApiOneImpl({
    required CreateWebMoneyAmountFromYookassaApiOne createWebMoneyAmountFromYookassaApiOne,
    required IsYookassaApiSucceededPaymentRevoked isYookassaApiSucceededPaymentRevoked,
  })  : _createWebMoneyAmountFromYookassaApiOne = createWebMoneyAmountFromYookassaApiOne,
        _isYookassaApiSucceededPaymentRevoked = isYookassaApiSucceededPaymentRevoked;

  final CreateWebMoneyAmountFromYookassaApiOne _createWebMoneyAmountFromYookassaApiOne;
  final IsYookassaApiSucceededPaymentRevoked _isYookassaApiSucceededPaymentRevoked;

  @override
  YookassaTransaction call({
    required YookassaTransaction transaction,
    required YookassaApiSucceededPayment apiPayment,
  }) {
    var updatedRevocationInfo = transaction.revocationInfo;

    final apiPaymentRevoked = _isYookassaApiSucceededPaymentRevoked(
      apiPayment: apiPayment,
    );

    if (apiPaymentRevoked) {
      final refundedAmount = _createWebMoneyAmountFromYookassaApiOne(
        yookassaApiMoneyAmount: apiPayment.refundedAmount,
      );

      if (transaction.revocationInfo == null) {
        final currentTime = DateTime.now().toUtc();

        updatedRevocationInfo = YookassaTransactionRevocationInfo(
          time: currentTime,
          refundedAmount: refundedAmount,
        );
      } else {
        updatedRevocationInfo = transaction.revocationInfo!.copyWith(
          refundedAmount: () => refundedAmount,
        );
      }
    }

    final incomeAmount = _createWebMoneyAmountFromYookassaApiOne(
      yookassaApiMoneyAmount: apiPayment.incomeAmount,
    );

    return transaction.copyWith(
      revocationInfo: () => updatedRevocationInfo,
      incomeAmount: () => incomeAmount,
    );
  }
}
